# @Version : 1.0
# @Author  : wxz
# @File    : uvicorn_log_config.py
# @Time    : 2025/6/14 10:43
# @Describe: 描述...
from uvicorn.config import LOGGING_CONFIG
import logging
import logging.config
from typing import Dict, Any

from config.app_logger import AppLogger


class UvicornLoggerWrapper:
    def __init__(self, app_logger: AppLogger):
        """
        Initialize Uvicorn logger wrapper

        Args:
            app_logger: Instance of your AppLogger class
        """
        self.app_logger = app_logger
        self._configure_uvicorn_logging()

    def _configure_uvicorn_logging(self):
        """Configure Uvicorn to use our custom logger"""
        # Get the Uvicorn logger names
        uvicorn_logger_names = [
            "uvicorn",
            "uvicorn.error",
            "uvicorn.access",
            "uvicorn.asgi"
        ]

        # Configure each Uvicorn logger to use our AppLogger
        for name in uvicorn_logger_names:
            logger = logging.getLogger(name)
            logger.handlers = []
            logger.propagate = True  # Let logs propagate to our root logger

        # Disable Uvicorn's default logging config
        LOGGING_CONFIG["disable_existing_loggers"] = True

    def get_uvicorn_log_config(self) -> Dict[str, Any]:
        """
        Get a Uvicorn-compatible logging configuration dictionary
        that routes all Uvicorn logs through our AppLogger.
        """
        return {
            "version": 1,
            "disable_existing_loggers": False,
            "loggers": {
                "uvicorn": {
                    "handlers": [],
                    "level": "INFO",
                    "propagate": True
                },
                "uvicorn.error": {
                    "handlers": [],
                    "level": "INFO",
                    "propagate": True
                },
                "uvicorn.access": {
                    "handlers": [],
                    "level": "INFO",
                    "propagate": True
                },
                "uvicorn.asgi": {
                    "handlers": [],
                    "level": "INFO",
                    "propagate": True
                }
            }
        }

    @staticmethod
    def intercept_uvicorn_logs(app_logger: AppLogger):
        """
        Intercept and reformat Uvicorn logs to match our application format.
        This should be called before starting the Uvicorn server.
        """

        # Access log formatting
        def access_log_formatter(record):
            client_addr = record.args.get('client_addr', '')
            method = record.args.get('method', '')
            full_path = record.args.get('full_path', '')
            status_code = record.args.get('status_code', '')

            msg = f"{client_addr} - \"{method} {full_path}\" {status_code}"
            app_logger.info(msg)
            return False  # Prevent original log from being emitted

        # Error log formatting
        def error_log_formatter(record):
            msg = record.getMessage()
            if record.levelno >= logging.ERROR:
                app_logger.error(msg)
            elif record.levelno >= logging.WARNING:
                app_logger.warning(msg)
            else:
                app_logger.info(msg)
            return False  # Prevent original log from being emitted

        # Add filters to Uvicorn loggers
        access_logger = logging.getLogger("uvicorn.access")
        error_logger = logging.getLogger("uvicorn.error")

        access_logger.addFilter(access_log_formatter)
        error_logger.addFilter(error_log_formatter)

        # Remove default handlers
        access_logger.handlers = []
        error_logger.handlers = []